package com.example.interceptor;

import com.example.ErrorEnum;
import com.example.annotation.IgnoreToken;
import com.example.base.DemoContext;
import com.example.base.DemoException;
import com.example.contanxt.Context;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.lang.reflect.Method;
import java.util.Objects;

public class TokenInterceptor implements HandlerInterceptor {

    private final Logger log = LoggerFactory.getLogger(TokenInterceptor.class);

    @SuppressWarnings("null")
    public boolean preHandle(HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) throws Exception {

        if (!(handler instanceof HandlerMethod method)) {
            return true;
        }
//
        // 3) 兜底放行常见不需要鉴权的系统端点（与 Security 白名单保持一致）
        String path = request.getRequestURI();
        if (path.startsWith("/error") ||
                path.startsWith("/actuator") ||
                path.startsWith("/swagger-ui") ||
                path.startsWith("/v3/api-docs") ||
                path.startsWith("/doc.html")) {
            return true;
        }


        HandlerMethod handlerMethod = (HandlerMethod) handler;

        Method methodToCheck = handlerMethod.getMethod();


        IgnoreToken ann =AnnotationUtils.findAnnotation(methodToCheck, IgnoreToken.class);

        if (ann == null) {
            ann = AnnotationUtils.findAnnotation(methodToCheck, IgnoreToken.class);
        }
//        if (ann == null) {
//            ann = AnnotationUtils.findAnnotation(method.getBeanType(), IgnoreToken.class);
//        }

        if(Objects.nonNull(ann)){
            log.info("当前方法有ignoreToken注解，无需校验token");
            return true;
        }
        if(!StringUtils.hasLength(request.getHeader(Context.HEAD_TOKEN))){
            throw new DemoException(ErrorEnum.LACK_TOKEN.getCode(), ErrorEnum.LACK_TOKEN.getMessage());
        }
        request.setAttribute(Context.HEAD_TOKEN,request.getHeader(Context.HEAD_TOKEN));
        DemoContext.setToken(request.getHeader(Context.HEAD_TOKEN));
        return true;
    }

    @SuppressWarnings("null")
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    

    /**
     * 请求完成后执行的方法
     * @param request HTTP请求对象
     * @param response HTTP响应对象
     * @param handler 处理器对象
     * @param ex 异常对象，可能为null
     * @throws Exception 可能抛出的异常
     */
    @SuppressWarnings("null")
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        log.info("当前用户调用完成前,上下文的token为:{}", DemoContext.getToken());
        DemoContext.clearToken();
        DemoContext.clearUser();
        log.info("当前用户调用完成后,上下文的token为:{}",DemoContext.getToken());
    }
}
